package com.zhoug.zmui;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.Gravity;

import com.zhoug.common.utils.JsonUtils;
import com.zhoug.common.utils.LogUtils;
import com.zhoug.common.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 文本对齐组件:支持左对齐,右对齐,居中对齐,分散对齐
 *
 * @Author 35574
 * @Date 2022/4/22
 * @Description
 */
public class ZMUIAlignmentTextView extends androidx.appcompat.widget.AppCompatTextView {
    private static final String TAG = ">>>ZMUIAlignmentTextView";
    private static final boolean debug = false;

    public static final int GRAVITY_START = 1;
    public static final int GRAVITY_END = 2;
    public static final int GRAVITY_CENTER = 3;
    public static final int GRAVITY_SCATTER = 4;
    private static final String REQUIRED_TAG = "*";//必填项标记
    private static final String COLON = ":";
    private static final int REQUIRED_TAG_COLOR = Color.RED;//必填项颜色

    /**
     * 文字对齐方式
     */
    private int mTextAlign;
    /**
     * 汉字个数
     */
    private int mTextEms;
    /**
     * 是否必填
     */
    private boolean mRequired;
    /**
     * 必填项占位:mRequired 为false时也会预留出星号位置
     */
    private boolean mRequiredPlaceholder;
    /**
     * 冒号占位
     */
    private boolean mColonPlaceholder;

    private int mRequiredTabGravity = GRAVITY_END;

    private String[] mWords;
    private List<String> mResultWord = new ArrayList<>();


    public ZMUIAlignmentTextView(Context context) {
        this(context, null);
    }

    public ZMUIAlignmentTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ZMUIAlignmentTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        parseAttr(context, attrs, defStyleAttr);
    }

    public void parseAttr(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ZMUIAlignmentTextView, defStyleAttr, R.style.ZMUIAlignTextView);
        int textAlign = typedArray.getInt(R.styleable.ZMUIAlignmentTextView_zmui_textAlign, GRAVITY_START);
        mTextEms = typedArray.getInt(R.styleable.ZMUIAlignmentTextView_zmui_textEms, 0);
        mRequired = typedArray.getBoolean(R.styleable.ZMUIAlignmentTextView_zmui_required, false);
        mRequiredPlaceholder = typedArray.getBoolean(R.styleable.ZMUIAlignmentTextView_zmui_requiredPlaceholder, false);
        mColonPlaceholder = typedArray.getBoolean(R.styleable.ZMUIAlignmentTextView_zmui_colonPlaceholder, false);
        mRequiredTabGravity = typedArray.getInt(R.styleable.ZMUIAlignmentTextView_zmui_requiredTabGravity, GRAVITY_END);
        String word = typedArray.getString(R.styleable.ZMUIAlignmentTextView_zmui_words);
        typedArray.recycle();
        setTextAlign(textAlign);
        if (!StringUtils.isNullOrEmpty(word)) {
            mWords = word.split(",");
        }
        if (debug) {
            LogUtils.d(TAG, "parseAttr:mTextAlign:" + textAlign);
            LogUtils.d(TAG, "parseAttr:mTextEms:" + mTextEms);
            LogUtils.d(TAG, "parseAttr:mRequired:" + mRequired);
            LogUtils.d(TAG, "parseAttr:mRequiredPlaceholder:" + mRequiredPlaceholder);
            LogUtils.d(TAG, "parseAttr:mRequiredTabGravity:" + mRequiredTabGravity);
            LogUtils.d(TAG, "parseAttr:mWords:" + (mWords != null ? JsonUtils.toJson(mWords) : null));
        }

    }

    private Paint.FontMetrics temptFontMetrics = new Paint.FontMetrics();

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //宽度不是固定值时,根据限制的中文字数测量宽度
        if (mTextEms > 0 && widthMode != MeasureSpec.EXACTLY) {
            int width;
            TextPaint paint = getPaint();
            paint.setTextSize(getTextSize());
            width = measureEmsWidth(paint);
            if (isRequiredSpace()) {
                width += paint.measureText(REQUIRED_TAG);
            }
            if (mColonPlaceholder) {
                width += paint.measureText(COLON);
            }
            width += getPaddingStart() + getPaddingEnd();
            if (widthMode == MeasureSpec.AT_MOST) {
                width = Math.min(width, widthSize);
            }
            if (debug) {
                LogUtils.d(TAG, "onMeasure:width=" + width);
            }
            //测量高度
            paint.getFontMetrics(temptFontMetrics);
            int height = (int) (temptFontMetrics.bottom - temptFontMetrics.top + getPaddingTop() + getPaddingBottom());
            super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    /**
     * 计算文本的宽度
     *
     * @param paint
     * @return
     */
    private int measureEmsWidth(Paint paint) {
        float singleChineseLength = paint.measureText("中");
        return (int) Math.ceil(singleChineseLength * mTextEms);
    }


    /**
     * 预留必填项标记"*"的空间
     *
     * @return
     */
    private boolean isRequiredSpace() {
        return mRequired || mRequiredPlaceholder;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (debug) {
            LogUtils.d(TAG, "onDraw:开始绘制");
        }
        if (mTextAlign == 0) {
            super.onDraw(canvas);
            return;
        }
        CharSequence charSequence = getText();
        if (charSequence == null || StringUtils.isNullOrEmpty(charSequence.toString())) {
            super.onDraw(canvas);
            return;
        }
        int width = getMeasuredWidth();
        TextPaint textPaint = getPaint();
        textPaint.setTextSize(getTextSize());
        String text = charSequence.toString();
        if (debug) {
            LogUtils.d(TAG, "onDraw:text=" + text);
        }
        //测量基准线
        Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
        int baseline = (getMeasuredHeight() - fontMetrics.bottom - fontMetrics.top) / 2;
        if (debug) {
            LogUtils.d(TAG, "onDraw:baseline=" + baseline);
        }
        if (mTextAlign == GRAVITY_SCATTER) {
            mResultWord.clear();
            if (debug) {
                LogUtils.d(TAG, "onDraw:分散对齐");
            }
            float textWidth = textPaint.measureText(isRequiredSpace() ? REQUIRED_TAG + text : text);
            if (textWidth >= width) {
                //内容超出边界
                float tagWidth = textPaint.measureText(REQUIRED_TAG);
                if (isRequiredSpace()) {
                    if (mRequiredTabGravity == GRAVITY_START) {
                        if (mRequired) {
                            textPaint.setColor(REQUIRED_TAG_COLOR);
                            textPaint.setTextAlign(Paint.Align.LEFT);
                            canvas.drawText(REQUIRED_TAG, 0, baseline, textPaint);
                        }

                        textPaint.setColor(getCurrentTextColor());
                        textPaint.setTextAlign(Paint.Align.LEFT);
                        canvas.drawText(text, tagWidth, baseline, textPaint);
                    } else {
                        if (mRequired) {
                            textPaint.setColor(REQUIRED_TAG_COLOR);
                            textPaint.setTextAlign(Paint.Align.RIGHT);
                            canvas.drawText(REQUIRED_TAG, width, baseline, textPaint);
                        }

                        textPaint.setColor(getCurrentTextColor());
                        textPaint.setTextAlign(Paint.Align.RIGHT);
                        canvas.drawText(text, width - tagWidth, baseline, textPaint);
                    }
                } else {
                    textPaint.setColor(getCurrentTextColor());
                    textPaint.setTextAlign(Paint.Align.LEFT);
                    canvas.drawText(text, 0, baseline, textPaint);
                }
            } else {
                groupByWords(text, mWords, 0, mResultWord);
                if (debug) {
                    LogUtils.d(TAG, "onDraw:mResultWord=" + JsonUtils.toJson(mResultWord));
                }
                if (mResultWord.size() > 1 && ":".equals(mResultWord.get(mResultWord.size() - 1))) {
                    mResultWord.remove(mResultWord.size() - 1);
                    mResultWord.add(mResultWord.remove(mResultWord.size() - 1) + ":");
                }
                if (debug) {
                    LogUtils.d(TAG, "onDraw:mResultWord=" + JsonUtils.toJson(mResultWord));
                }
                float startX = 0;
                if (isRequiredSpace() && mRequiredTabGravity == GRAVITY_START) {
                    if (mRequired) {
                        textPaint.setColor(REQUIRED_TAG_COLOR);
                        textPaint.setTextAlign(Paint.Align.LEFT);
                        canvas.drawText(REQUIRED_TAG, 0, baseline, textPaint);
                    }
                    startX = textPaint.measureText(REQUIRED_TAG);
                }
                textPaint.setColor(getCurrentTextColor());
                //间距
                float horizontalSpace = (width - textWidth) / (mResultWord.size() - 1);
                int lastIndex = mResultWord.size() - 1;
                for (int index = 0; index <= lastIndex; index++) {
                    String s = mResultWord.get(index);
                    canvas.drawText(s, startX, baseline, textPaint);
                    startX += textPaint.measureText(s);
                    if (index < lastIndex) {
                        startX += horizontalSpace;
                    }
                }
                if (mRequired && mRequiredTabGravity == GRAVITY_END) {
                    textPaint.setColor(REQUIRED_TAG_COLOR);
                    textPaint.setTextAlign(Paint.Align.LEFT);
                    canvas.drawText(REQUIRED_TAG, startX, baseline, textPaint);
                }
            }
        } else {
            //正文长度
            float textWidth = textPaint.measureText(text);
            float tagWidth = textPaint.measureText(REQUIRED_TAG);
            float textStartX = 0;
            float tagStartX = 0;
            if (mTextAlign == GRAVITY_START) {
                if (debug) {
                    LogUtils.d(TAG, "onDraw:左对齐");
                }
                if (isRequiredSpace()) {
                    if (mRequiredTabGravity == GRAVITY_START) {
                        tagStartX = 0;
                        textStartX = tagStartX + tagWidth;
                    } else {
                        if (textWidth + tagWidth <= width) {
                            textStartX = 0;
                            tagStartX = textStartX + textWidth;
                        } else {
                            tagStartX = width - tagWidth;
                            textStartX = tagStartX - textWidth;
                        }
                    }
                } else {
                    textStartX = 0;
                }
            } else if (mTextAlign == GRAVITY_CENTER) {
                if (debug) {
                    LogUtils.d(TAG, "onDraw:居中对齐");
                }
                textStartX = (width - textWidth) / 2;
                if (isRequiredSpace()) {
                    if (mRequiredTabGravity == GRAVITY_START) {
                        if (textStartX - tagWidth >= 0) {
                            tagStartX = textStartX - tagWidth;
                        } else {
                            tagStartX = 0;
                            textStartX = tagStartX + tagWidth;
                        }
                    } else {
                        if (textStartX + textWidth + tagWidth <= width) {
                            tagStartX = textStartX + textWidth;
                        } else {
                            tagStartX = width - tagWidth;
                            textStartX = tagStartX - textWidth;
                        }
                    }
                }
            } else if (mTextAlign == GRAVITY_END) {
                if (debug) {
                    LogUtils.d(TAG, "onDraw:右对齐");
                }
                textStartX = width - textWidth;
                if (isRequiredSpace()) {
                    if (mRequiredTabGravity == GRAVITY_START) {
                        if (textStartX - tagWidth >= 0) {
                            tagStartX = textStartX - tagWidth;
                        } else {
                            tagStartX = 0;
                            textStartX = tagStartX + tagWidth;
                        }
                    } else {
                        if (textStartX + textWidth + tagWidth <= width) {
                            tagStartX = textStartX + textWidth;
                        } else {
                            tagStartX = width - tagWidth;
                            textStartX = tagStartX - textWidth;
                        }
                    }
                }
            }
            textPaint.setColor(getCurrentTextColor());
            textPaint.setTextAlign(Paint.Align.LEFT);
            canvas.drawText(text, textStartX, baseline, textPaint);
            if (mRequired) {
                textPaint.setColor(REQUIRED_TAG_COLOR);
                textPaint.setTextAlign(Paint.Align.LEFT);
                canvas.drawText(REQUIRED_TAG, tagStartX, baseline, textPaint);
            }
        }
    }

    /**
     * 分组
     *
     * @param text
     * @param words
     * @param wordIndex
     * @param result
     */
    private static List<String> groupByWords(String text, String[] words, int wordIndex, List<String> result) {
        if (words == null || words.length == 0) {
            char[] chars = text.toCharArray();
            for (char item : chars) {
                add(result, String.valueOf(item));
            }
            return result;
        }
        String word = words[wordIndex];
        int nextWordIndex = wordIndex + 1;
        if (debug) {
            LogUtils.d(TAG, "groupByWords:result=" + JsonUtils.toJson(result));
        }
        if (text.startsWith(word)) {
            add(result, word);
            text = text.substring(word.length());
        }
        if (debug) {
            LogUtils.d(TAG, "groupByWords:wordIndex=" + wordIndex + ",word=" + word + ",text=" + text);
        }
        String[] split = text.split(word);
        if (debug) {
            LogUtils.d(TAG, "groupByWords:split=" + JsonUtils.toJson(split));
        }
        if (split.length == 1) {
            String s1 = split[0];
            if (nextWordIndex < words.length) {
                groupByWords(s1, words, nextWordIndex, result);
            } else {
                if (!s1.equals(word) && s1.length() > 1) {
                    char[] chars = s1.toCharArray();
                    for (char item : chars) {
                        add(result, String.valueOf(item));
                    }
                } else {
                    add(result, s1);
                }
            }
        } else {
            for (int i = 0; i < split.length; i++) {
                String group = split[i];
                if (nextWordIndex < words.length) {
                    groupByWords(group, words, nextWordIndex, result);
                } else {
                    if (!group.equals(word) && group.length() > 1) {
                        char[] chars = group.toCharArray();
                        for (char item : chars) {
                            add(result, String.valueOf(item));
                        }
                    } else {
                        add(result, group);
                    }
                }
                if (i < split.length - 1 || text.endsWith(word)) {
                    add(result, word);
                }
            }
        }
        return result;
    }

    private static void add(List<String> result, String s) {
        if (s != null && !"".equals(s)) {
            if (s.contains("\\")) {
                result.add(s.replace("\\", ""));
            } else {
                result.add(s);
            }
        }
    }

    /**
     * 文字对齐方式
     *
     * @param textAlign {@link #GRAVITY_START,#GRAVITY_CENTER,#GRAVITY_END,#GRAVITY_SCATTER}
     */
    public void setTextAlign(int textAlign) {
        this.mTextAlign = textAlign;
        //左对齐,居中对齐,右对齐使用系统功能
        switch (mTextAlign) {
            case GRAVITY_START:
                setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
                break;
            case GRAVITY_END:
                setGravity(Gravity.END | Gravity.CENTER_VERTICAL);
                break;
            case GRAVITY_CENTER:
                setGravity(Gravity.CENTER);
                break;
        }
    }

    /**
     * 汉字个数
     *
     * @param textEms
     */
    public void setTextEms(int textEms) {
        this.mTextEms = textEms;
    }

    /**
     * 是否必填项
     *
     * @param required
     */
    public void setRequired(boolean required) {
        this.mRequired = required;
    }

    /**
     * 必填项占位:mRequired 为false时也会预留出星号位置
     *
     * @param requiredPlaceholder
     */
    public void setRequiredPlaceholder(boolean requiredPlaceholder) {
        this.mRequiredPlaceholder = requiredPlaceholder;
    }

    /**
     * 冒号占位
     *
     * @param colonPlaceholder
     */
    public void setColonPlaceholder(boolean colonPlaceholder) {
        this.mColonPlaceholder = colonPlaceholder;
    }

    /**
     * 必填项标记"*"位置
     *
     * @param requiredTabGravity {@link #GRAVITY_START,#GRAVITY_END}
     */
    public void setRequiredTabGravity(int requiredTabGravity) {
        this.mRequiredTabGravity = requiredTabGravity;
    }

    /**
     * 作为一个单词处理
     *
     * @param words
     */
    public void setWords(String[] words) {
        this.mWords = words;
    }

}
